package per.turtle.system.controller;

import cn.hutool.core.util.StrUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import per.turtle.common.core.constant.CacheConstants;
import per.turtle.common.core.web.controller.BaseController;
import per.turtle.common.core.web.entity.CommonResult;
import per.turtle.common.core.web.page.TableDataInfo;
import per.turtle.common.log.annotation.Log;
import per.turtle.common.log.enums.BusinessType;
import per.turtle.common.redis.service.RedisService;
import per.turtle.common.security.annotation.PreAuthorize;
import per.turtle.system.dto.LoginUser;
import per.turtle.system.dto.SysUserOnline;
import per.turtle.system.service.ISysUserOnlineService;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * @author turtle
 */
@AllArgsConstructor
@RequestMapping("online")
@RestController
@Tag(name = "在线用户监控", description = "userOnline_在线用户监控模块")
public class SysUserOnlineController extends BaseController {

    private final ISysUserOnlineService userOnlineService;

    private final RedisService redisService;

    @Operation(summary = "强退用户", description = "强退用户")
    @DeleteMapping("{tokenId}")
    @Log(title = "在线用户", businessType = BusinessType.FORCE)
    @PreAuthorize(hasPermission = "monitor:online:forceLogout")
    public CommonResult<Void> forceLogout(@PathVariable String tokenId) {
        redisService.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId);
        return CommonResult.success();
    }

    @Operation(summary = "获取在线用户列表或分页", description = "获取在线用户列表或分页（区别于是否传入分页参数）")
    @GetMapping("list")
    @PreAuthorize(hasPermission = "monitor:online:list")
    public TableDataInfo<SysUserOnline> list(String ipaddr, String userName) {
        Collection<String> keys = redisService.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
        List<SysUserOnline> userOnlineList = new ArrayList<>();
        for (String key : keys) {
            LoginUser user = redisService.getCacheObject(key);
            if (StrUtil.isNotEmpty(ipaddr) && StrUtil.isNotEmpty(userName)) {
                if (StrUtil.equals(ipaddr, user.getIpaddr()) && StrUtil.equals(userName, user.getUsername())) {
                    userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user));
                }
            } else if (StrUtil.isNotEmpty(ipaddr)) {
                if (StrUtil.equals(ipaddr, user.getIpaddr())) {
                    userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user));
                }
            } else if (StrUtil.isNotEmpty(userName)) {
                if (StrUtil.equals(userName, user.getUsername())) {
                    userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user));
                }
            } else {
                userOnlineList.add(userOnlineService.loginUserToUserOnline(user));
            }
        }
        Collections.reverse(userOnlineList);
        userOnlineList.removeAll(Collections.singleton(null));
        return getDataTable(userOnlineList);
    }

}
